/**
 * verify. [Middleware] 校验请求是否有效
 *
 * @param {ExpressRequest} req
 * @param {ExpressResponse} res
 * @param {Function} next
 */
const verify = (req, res, next) => {
  const { source, timestamp, sign } = req.query;
  if (!source || !timestamp || !sign) {
    return res.status(400).send({ status: 40001, message: 'PARAMETERS_MISSING' });
  }

  const heart = req.app.get('idents').find((v) => v.source == source);
  // 时间戳是否同步
  const interval = Math.abs(timestamp - new Date() / 1000);
  if (interval > 60 * 3) {
    return res.status(400).send({ status: 40002, message: 'TIMESTAMP_INVALID' });
  }

  // 是否有效来源
  if (!heart) {
    return res.status(401).send({ status: 40101, message: 'SOURCE_NOT_FOUND' });
  }

  // 计算校验码是否一致
  if (!isValid(heart, timestamp, sign)) {
    return res.status(401).send({ status: 40102, message: 'UNAUTHORIZED' });
  }

  req.heart = heart;
  next();
};

/**
 * isValid. 校验结果是否符合正确
 *
 * @param {} heart
 * @param {} source
 * @param {} timestamp
 * @param {} sign
 */
const isValid = (heart, timestamp, sign) => {
  return doSign(heart.source, heart.secret, timestamp) == sign;
};

/**
 * doSign. 进行校验
 *
 * @param {} source
 * @param {} timestamp
 * @param {} secret
 */
const doSign = (source, secret, timestamp) => {
  const text = `${source}:${secret}:${timestamp}`;
  const sign = require('crypto').createHash('md5').update(text).digest('hex');
  return sign;
};

module.exports = {
  verify,
  doSign,
};
